#include "mysql_execute.h"


mysql_execute::mysql_execute()
{
	mysql_ = mysql_connect::get()->getConnection();
	query_ = false;
}


mysql_execute::~mysql_execute()
{
	if (mysql_){
		mysql_connect::get()->releaseConnection(mysql_);
	}
}

MYSQL_RES* mysql_execute::query(const char* sqlStr)
{
	if (mysql_ == NULL) return NULL;

	if (mysql_query(mysql_, sqlStr) == 0)
	{
		return mysql_store_result(mysql_);
	}
	printf("error: Query fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return NULL;
}
int mysql_execute::Delete(const char* sqlStr)
{
	if (mysql_ == NULL) return -1;

	if (mysql_query(mysql_, sqlStr) == 0){
		return 0;
	}
	printf("error: Delete fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}
int     mysql_execute::ExcuteProc(const char* sqlStr)
{
	if (mysql_ == NULL) return -1;

	if (mysql_query(mysql_, sqlStr) == 0)
	{
		return 0;
	}
	printf( "error:ExcuteProc fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

int     mysql_execute::ExcuteProc(const char* sqlStr, int &nReturn)
{
	//int nLen = strlen(sqlStr);
	nReturn = -1;
	if (mysql_ == NULL) return -1;

	if (mysql_query(mysql_, sqlStr) == 0)
	{
		std::stringstream sqlOut;
		sqlOut << "select @out_code";
		if (mysql_query(mysql_, sqlOut.str().c_str()) == 0)
		{
			MYSQL_RES *result = NULL;
			if ((result = mysql_store_result(mysql_)))
			{
				MYSQL_ROW  row = ::mysql_fetch_row(result);
				if (row[0])
				{
					nReturn = atoi(row[0]);
				}
				free_result(result);
				return 0;
			}
		}
	}
	printf("error: ExcuteProc fail code=%d,error msg=%s", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

int     mysql_execute::ExcuteProc2(const char* sqlStr, int nReturn[])
{
	//nReturn = -1;
	if (mysql_ == NULL) return -1;

	if (mysql_query(mysql_, sqlStr) == 0)
	{
		std::stringstream sqlOut;
		sqlOut << "select @out_ret,@out_id";
		if (mysql_query(mysql_, sqlOut.str().c_str()) == 0)
		{
			MYSQL_RES *result = NULL;
			if ((result = mysql_store_result(mysql_)))
			{
				MYSQL_ROW  row = ::mysql_fetch_row(result);
				if (row[0])
				{
					nReturn[0] = atoi(row[0]);
				}
				else
				{
					nReturn[0] = 0;
				}

				if (row[1])
				{
					nReturn[1] = atoi(row[1]);
				}
				else
				{
					nReturn[1] = 0;
				}
				free_result(result);
				return 0;
			}

		}

	}
	printf("error:ExcuteProc fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}
int     mysql_execute::ExcuteProc3(const char* sqlStr, double nReturn[])
{
	//nReturn = -1;
	if (mysql_ == NULL) return -1;

	if (mysql_query(mysql_, sqlStr) == 0)
	{
		std::stringstream sqlOut;
		sqlOut << "select @out_ret,@out_id";
		if (mysql_query(mysql_, sqlOut.str().c_str()) == 0)
		{
			MYSQL_RES *result = NULL;
			if ((result = mysql_store_result(mysql_)))
			{
				MYSQL_ROW  row = ::mysql_fetch_row(result);
				if (row[0])
				{
					nReturn[0] = atof(row[0]);
				}
				else
				{
					nReturn[0] = 0.0;
				}

				if (row[1])
				{
					nReturn[1] = atoi(row[1]);
				}
				else
				{
					nReturn[1] = 0;
				}
				free_result(result);
				return 0;
			}

		}

	}
	printf("error:ExcuteProc fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

/*int   mysql_execute::ExcuteProcRecord(const char* sqlStr, int nReturn[])
{


}*/

MYSQL_RES *mysql_execute::query_more(const char* sqlStr)
{
	if (mysql_ == NULL) return NULL;
	if (query_ == false)
	{
		query_ = true;
		if (mysql_query(mysql_, sqlStr) != 0)
		{
			query_ = false;
			return NULL;
		}
		
		MYSQL_RES *res = mysql_store_result(mysql_);
		if (res == NULL)
		{
			query_ = false;
		}
		return res;
	}
	else
	{
		mysql_next_result(mysql_);
		MYSQL_RES *res = mysql_store_result(mysql_);
		if (res == NULL)
		{
			query_ = false;
		}
		return res;	
	}
	return NULL;
}

void mysql_execute::free_result(MYSQL_RES* result)
{
	if (mysql_ == NULL) return;

	if (result){
		mysql_free_result(result);
	}

	while (!mysql_next_result(mysql_))
	{
		MYSQL_RES* result_ptr = mysql_store_result(mysql_);
		if (result_ptr)
			mysql_free_result(result_ptr);
	}
}

void mysql_execute::free_result(MYSQL_RES* result, int m)
{
	if (mysql_ == NULL) return;
	if (result){
		mysql_free_result(result);
	}
	if (m == 1)
	{
		while (!mysql_next_result(mysql_))
		{
		MYSQL_RES* result_ptr = mysql_store_result(mysql_);
		if (result_ptr)
		mysql_free_result(result_ptr);
		}
	}
}

int mysql_execute::update(const char* sql)
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, sql) == 0)
		return 0;
	printf( "error:Insert fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

std::string& mysql_execute::getError()
{
	return StrError;
}

int mysql_execute::insert(const char* sql)
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, sql) == 0)
		return 0;
	printf( "error:Insert fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

int mysql_execute::insert_id(const char* sqlStr)
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, sqlStr) == 0)
	{
		return mysql_insert_id(mysql_);
	}
	printf("error:Insert fail code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
	return -1;
}

MYSQL* mysql_execute::mysql()
{
	return mysql_;
}

int mysql_execute::startTransaction()
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, "set autocommit=0") != 0)
	{
		printf("error:Fail to turn off auto commit mode code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
		return -1;
	}

	return 0;
}

int mysql_execute::commit()
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, "commit") != 0)
	{
		printf("error:Commit transaction failed code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
		return -1;
	}
	return 0;
}

int mysql_execute::rollback()
{
	if (mysql_ == NULL) return -1;
	if (mysql_query(mysql_, "rollback") != 0)
	{
		printf("error:Transaction rollback failed code=%d,error msg=%s \n", mysql_errno(mysql_), mysql_error(mysql_));
		return -1;
	}
	return 0;
}